<template>
  <div id="scriptExecution">
    <ReturnPage />
    <div class="mt20">
      <el-button type="primary" size="mini" @click="
        changeList = true;
      getListData();
      ">历史记录</el-button>
      <el-button type="primary" size="mini" @click="
        changeList = false;
      getListData();
      ">任务列表</el-button>
      <el-button type="primary" size="mini" @click="
        dialogVisible = true;
      editOrAdd = true;
      " v-if="!changeList">添加任务</el-button>
      <!-- 历史记录 -->
      <div class="tp_box mt20" v-if="changeList">
        <el-table height="calc(100vh - 280px)" :data="historyData" style="width: 100%">
          <el-table-column prop="scriptName" label="脚本名称">
          </el-table-column>
          <el-table-column prop="content" label="命令" show-overflow-tooltip>
          </el-table-column>
          <el-table-column prop="executeTime" label="执行时间">
          </el-table-column>
          <el-table-column prop="type" label="类型">
            <template slot-scope="scope">
              <el-tag type="success">{{
                scope.row.executeType == 1 ? "手动" : "自动"
              }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="executeResult" label="执行结果">
          </el-table-column>
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button type="primary" size="mini" @click="executeAgain(scope.row)">再次执行</el-button>
              <el-button type="primary" size="mini" @click="detail(scope.row.id)">详情</el-button>
            </template>
          </el-table-column>
        </el-table>
        <pagination v-show="historyData.length > 0" :total="total" :page.sync="query.pageNum" :limit.sync="query.pageSize"
          @pagination="getListData" />
      </div>

      <!-- 任务列表 -->
      <div class="tp_box mt20" v-else>
        <el-table height="calc(100vh - 280px)" :data="tableData" style="width: 100%">
          <el-table-column prop="taskName" label="任务名称" show-overflow-tooltip>
          </el-table-column>
          <el-table-column prop="scriptName" label="脚本名称" show-overflow-tooltip>
          </el-table-column>
          <el-table-column prop="content" label="脚本内容" show-overflow-tooltip></el-table-column>
          <el-table-column prop="executeType" label="执行方式">
            <template slot-scope="scope">
              <el-tag type="success">{{
                scope.row.executeType == 1 ? "手动执行" : "定时执行"
              }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="createTime" label="创建时间" show-overflow-tooltip></el-table-column>
          <!-- <el-table-column prop="executeResult" label="执行结果">
          </el-table-column> -->
          <el-table-column label="操作" width="250px">
            <template slot-scope="scope">
              <el-button type="primary" size="mini" @click="showEditScriptTask(scope.row)">编辑</el-button>
              <el-button type="danger" size="mini" @click="delScriptTask(scope.row.id)">删除</el-button>
              <el-button type="primary" size="mini" @click="execute(scope.row)">立即执行</el-button>
            </template>
          </el-table-column>
        </el-table>
        <pagination v-show="tableData.length > 0" :total="total" :page.sync="query.pageNum" :limit.sync="query.pageSize"
          @pagination="getListData" />
      </div>

      <!-- 添加任务弹窗 -->
      <el-dialog :title="editOrAdd ? '添加任务' : '编辑任务'" :visible.sync="dialogVisible" @open="openDialog"
        @close="closeDialog('ruleForm')">
        <el-form :model="ruleForm" :rules="rules" size="mini" ref="ruleForm" label-width="100px" class="demo-ruleForm">
          <el-form-item label="脚本仓库" prop="scriptId">
            <el-select v-model="ruleForm.scriptId" placeholder="请选择脚本" style="width: 300px" @change="changeSelect">
              <el-option :label="item.name" :value="item.scriptId" v-for="(item, index) in scriptData"
                :key="index"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="任务名称" prop="taskName">
            <el-input v-model="ruleForm.taskName" placeholder="请输入任务名称" style="width: 300px"></el-input>
          </el-form-item>
          <el-form-item label="脚本内容" prop="content">
            <div id="editorJson" class="json-editor" />
          </el-form-item>
          <el-form-item label="执行方式" prop="executeType">
            <el-radio-group v-model="ruleForm.executeType">
              <el-radio :label="1">手动执行</el-radio>
              <el-radio :label="2">定时执行</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="执行时间" prop="executeTime" v-if="ruleForm.executeType == 2">
            <el-date-picker v-model="ruleForm.executeTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetime"
              placeholder="选择执行日期时间">
            </el-date-picker>
          </el-form-item>
          <el-form-item label="执行周期" prop="executePeriod" v-if="ruleForm.executeType == 2">
            <el-select v-model.number="ruleForm.executePeriod" placeholder="请选择执行周期" style="width: 300px">
              <el-option label="单次" :value="4"></el-option>
              <el-option label="每天" :value="1"></el-option>
              <el-option label="每周" :value="2"></el-option>
              <el-option label="每月" :value="3"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="submitForm('ruleForm')">{{
              editOrAdd
              ? ruleForm.executeType == 1
                ? "立即执行"
                : "添加任务"
              : "提交修改"
            }}</el-button>
            <el-button @click="resetForm('ruleForm')">重置</el-button>
          </el-form-item>
        </el-form>
      </el-dialog>

      <!-- 详情 -->
      <el-dialog title="详情" :visible.sync="dialogVisible_message" width="60%">
        <el-descriptions :column="3">
          <el-descriptions-item label="任务名称">{{
            historyDetail.taskName
          }}</el-descriptions-item>
          <el-descriptions-item label="脚本名称">{{
            historyDetail.scriptName
          }}</el-descriptions-item>
          <el-descriptions-item label="脚本内容">{{
            historyDetail.content
          }}</el-descriptions-item>
          <el-descriptions-item label="类型">
            <el-tag size="small">{{ historyDetail.type | getType }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="描述">{{
            historyDetail.description
          }}</el-descriptions-item>
          <el-descriptions-item label="超时">{{
            historyDetail.timeout
          }}</el-descriptions-item>
          <el-descriptions-item label="执行方式">{{
            historyDetail.executeType == 1 ? "手动执行" : "定时执行"
          }}</el-descriptions-item>
          <el-descriptions-item label="执行周期" v-if="historyDetail.executeType == 1">{{
            historyDetail.executePeriod == 1
            ? "每天"
            : historyDetail.executePeriod == 2
              ? "每周"
              : "每月"
          }}</el-descriptions-item>
          <el-descriptions-item label="执行时间">{{
            historyDetail.executeTime
          }}</el-descriptions-item>
          <el-descriptions-item label="创建时间">{{
            historyDetail.createTime
          }}</el-descriptions-item>
        </el-descriptions>
        <el-form :model="historyDetail">
          <el-form-item label="执行结果">
            <el-input type="textarea" disabled :rows="6" placeholder="请输入内容" v-model="historyDetail.outcome">
            </el-input>
          </el-form-item>
        </el-form>

        <span slot="footer" class="dialog-footer">
          <el-button type="primary" @click="dialogVisible_message = false">关 闭</el-button>
        </span>
      </el-dialog>
    </div>
  </div>
</template>

<script>
//接口
import {
  getScriptTaskList_Api, //获取脚本任务列表
  addScriptTask_Api, //添加脚本任务
  editScriptTask_Api, //编辑脚本任务
  delScriptTask_Api, //删除脚本任务
  getHistoryList_Api, //历史记录
  getScriptTaskDetail_Api, //任务详情
  executeAgain_Api, //再次执行
} from "@/api/automated/script.js";
import {
  getScriptList_Api, //脚本列表
} from "@/api/automated/script.js";
//代码编辑器
import { beautifierConf } from "@/utils/index";
import loadMonaco from "@/utils/loadMonaco";
import loadBeautifier from "@/utils/loadBeautifier";
let beautifier;
let monaco;
export default {
  data() {
    return {
      //脚本执行结果
      formInline: {
        result: "hahah",
      },
      //详情
      historyDetail: {},
      dialogVisible_message: false,
      //编辑false   添加true
      editOrAdd: false,
      //脚本数据
      scriptData: [],
      //历史记录数据
      historyData: [],
      //分页
      query: {
        pageNum: 1,
        pageSize: 10,
      },
      total: 0,
      //表单
      changeList: true,
      ruleForm: {
        scriptId: null, //脚本的id
        taskName: "", //脚本名称
        executeType: 1, //执行方式
        content: "", //脚本内容
        executePeriod: null, //执行周期
        executeTime: null, //执行时间

        hostId: "", //主机id
      },
      //表单验证规则
      rules: {
        //任务名称
        taskName: [
          { required: true, message: "请输入任务名称", trigger: "blur" },
        ],
        //脚本id
        scriptId: [
          { required: true, message: "请选择脚本", trigger: "change" },
        ],
        //执行方式
        executeType: [
          { required: true, message: "请选择执行方式", trigger: "change" },
        ],
        //脚本内容
        content: [
          { required: true, message: "请输入脚本内容", trigger: "change" },
        ],
        //执行周期
        executePeriod: [
          { required: true, message: "请选择执行周期", trigger: "change" },
        ],
        //执行时间
        executeTime: [
          { required: true, message: "请选择执行周期", trigger: "change" },
        ],

        hostId: [
          { required: true, message: "请选择主机群组", trigger: "change" },
        ],
      },
      jsonEditor: null, //编辑器对象
      dialogVisible: false, //控制添加任务弹框
      //列表数据
      tableData: [],
      //主机群组
      hostGroup: [],
    };
  },
  created() {
    this.getScriptData(); //获取脚本数据
    this.getListData(); //获取脚本列表
  },
  methods: {
    //获取脚本列表数据
    getListData() {
      if (this.changeList) {
        //历史记录
        getHistoryList_Api(this.query).then((res) => {
          this.historyData = res.rows;
          this.total = res.total;
        });
      } else {
        //任务列表
        getScriptTaskList_Api(this.query).then((res) => {
          this.tableData = res.rows;
          this.total = res.total;
        });
      }
    },
    //获取脚本数据
    getScriptData() {
      getScriptList_Api({
        pageNum: 1,
        pageSize: 1000,
        scope: 2,
      }).then((res) => {
        this.scriptData = res.rows;
      });
    },
    //再次执行
    executeAgain(row) {
      executeAgain_Api({
        id: row.id,
        isFromHistory: 1,
        scriptId: row.scriptId,
        hostId: row.hostId,
      }).then((res) => {
        this.$message.success("操作成功");
      });
      // executeAgain_Api({
      //   id: 1813323793,
      //   isFromHistory: 0,
      //   scriptId: "13",
      //   hostId: 10084,
      // }).then((res) => {
      //   this.$message.success("操作成功");
      // });
    },
    //立即执行
    execute(row) {
      executeAgain_Api({
        id: row.id,
        isFromHistory: 0,
        scriptId: row.scriptId,
        hostId: row.hostId,
      }).then((res) => {
        this.$message.success("操作成功");
      });
      // executeAgain_Api({
      //   id: 1813323793,
      //   isFromHistory: 0,
      //   scriptId: "13",
      //   hostId: 10084,
      // }).then((res) => {
      //   this.$message.success("操作成功");
      // });
    },

    //添加或编辑脚本任务
    submitForm(formName) {
      this.ruleForm.hostId = this.$route.query.hostid;
      //找到脚本数据里面的选中项
      const scriptObj = this.scriptData.find(
        (item) => item.scriptId == this.ruleForm.scriptId
      );
      this.ruleForm.type = scriptObj.type;
      this.ruleForm.scriptName = scriptObj.name;
      const tempObj = this.deleteObjectItem(this.ruleForm);
      this.$refs[formName].validate((valid) => {
        if (valid) {
          if (this.editOrAdd) {
            //添加
            addScriptTask_Api(tempObj).then((res) => {
              this.$message.success(res.msg);
              this.dialogVisible = false;
              this.getListData();
            });
          } else {
            //编辑
            editScriptTask_Api(tempObj).then((res) => {
              this.$message.success(res.msg);
              this.dialogVisible = false;
              this.getListData();
            });
          }
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    //详情
    detail(id) {
      getScriptTaskDetail_Api(id).then((res) => {
        this.dialogVisible_message = true;
        this.historyDetail = res.data;
      });
    },
    //删除脚本任务
    delScriptTask(id) {
      this.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          delScriptTask_Api(id).then((res) => {
            this.getListData();
            this.$message.success("操作成功");
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
    //显示编辑脚本任务弹窗
    showEditScriptTask(row) {
      this.editOrAdd = false;
      this.ruleForm = { ...row };
      this.dialogVisible = true;
    },
    //编辑脚本任务
    editScriptTask() { },

    //关闭弹窗
    closeDialog(formName) {
      this.ruleForm = {
        scriptId: null, //脚本的id
        taskName: "", //脚本名称
        executeType: 1, //执行方式
        content: "", //脚本内容
        executePeriod: null, //执行周期
        executeTime: null, //执行时间
      };
      this.$refs[formName].resetFields();
    },
    //切换选择的脚本
    changeSelect(val) {
      const checkedScript = this.scriptData.find((item) => item.id == val);
      //回显名字
      this.ruleForm.taskName = checkedScript.name;
      //回显脚本内容
      this.ruleForm.content = checkedScript.content;
      this.onOpen();
    },
    //重置表单
    resetForm(formName) {
      this.$refs[formName].resetFields();
      this.onOpen();
    },
    //格式化代码
    onOpen() {
      loadBeautifier((btf) => {
        beautifier = btf;
        this.beautifierJson = beautifier.js(
          this.ruleForm.content,
          beautifierConf.js
        );

        loadMonaco((val) => {
          monaco = val;
          this.setEditorValue("editorJson", this.beautifierJson);
        });
      });
    },
    //打开弹窗时，调用创建编辑器的方法
    openDialog() {
      this.$nextTick(() => {
        this.onOpen(); //创建编辑器
      });
    },
    //创建编辑器对象
    setEditorValue(id, codeStr) {
      const editorJson = document.getElementById(id);
      if (this.jsonEditor) {
        this.jsonEditor.setValue(codeStr);
      } else {
        this.jsonEditor = monaco.editor.create(editorJson, {
          value: codeStr,
          theme: "vs-dark",
          language: "java",
          automaticLayout: true,
        });
      }

      this.jsonEditor.onDidChangeModelContent((event) => {
        this.ruleForm.content = this.jsonEditor.getValue();
      });
    },
    //切换脚本来源时显示Monaco
    /* showMonaco() {
      if (this.ruleForm.executeType == 1) {
        this.onOpen();
      } else this.jsonEditor = null;
    }, */
    //获取主机群组
    /* getHostGroup() {
      getHostListGroup_Api().then((res) => {
        this.hostGroup = res.data;
      });
    }, */
    //提交表单之前，删除不需要的项
    deleteObjectItem({ ...object }) {
      if (object.executeType == 1) {
        delete object.executePeriod;
        delete object.executeTime;
      }
      return object;
    },
  },
  mounted() { },
  filters: {
    //格式化脚本类型
    getType(val) {
      switch (val) {
        case 0:
          return "脚本";
        case 1:
          return "IPMI";
        case 2:
          return "SSH";
        case 3:
          return "Telnet";
        default:
          return "WebHook";
      }
    },
    //根据groupid找出主机群组名称
    getHostGroupNameByid(val, hostGroup) {
      return hostGroup.find((item) => item.groupid == val)?.name;
    },
  },
};
</script>

<style lang="scss" scoped>
.json-editor {
  border: 1px solid #d3d3d3;
  border-radius: 5px;
  overflow: hidden;
  height: 200px;
}
</style>